import math
import os
import logging
from PyQt5.QtWidgets import QApplication, QWidget
from PyQt5.QtCore import Qt, QTimer, QPoint, QRect, QSize
from PyQt5.QtGui import QPainter, QColor, QPen, QBrush, QFont, QFontMetrics, QIcon
from voice_assistant.my_state import app_state
from voice_assistant.event_system import event_system, Events

logger = logging.getLogger("FloatingMicWindow")

# 浮动的圆形语音助理窗口, 最顶层悬浮，可随鼠标移动，不可关闭，提供麦克风状态指示功能
class FloatingMicWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Voice Assistant")
        self.setWindowFlags(
            Qt.FramelessWindowHint | 
            Qt.WindowStaysOnTopHint | 
            Qt.Tool
        )
        self.setAttribute(Qt.WA_TranslucentBackground)
        
        # 初始化通知数据
        self.notification_data = None
        
        # 订阅UI_NOTIFICATION事件
        event_system.subscribe(Events.UI_NOTIFICATION, self.handle_notification)
        
        # 窗口大小
        self.window_size = QSize(120, 120)
        self.setFixedSize(self.window_size)
        
        # 计算右上角位置
        screen_geometry = QApplication.desktop().availableGeometry()
        x_pos = screen_geometry.width() - self.width() - 10
        y_pos = 50
        self.move(x_pos, y_pos)
        
        # 初始化拖动功能
        self.drag_position = QPoint()
        self.dragging = False
        
        # 动画效果计数器
        self.animation_counter = 0
        
        # 设置字体
        self.command_font = QFont("Segoe UI", 8)
        self.indicator_font = QFont("Arial", 10)
        self.indicator_font.setBold(True)
        
        # 启动UI更新定时器
        self.update_timer = QTimer(self)
        self.update_timer.timeout.connect(self.update_ui)
        self.update_timer.start(200)  # 80ms更新一次
        
        # 初始化命令字典
        self.commands = {}
        
    def add_command(self, name, callback):
        """注册语音命令"""
        self.commands[name] = callback
        
    def paintEvent(self, event):
        painter = QPainter(self)
        painter.setRenderHint(QPainter.Antialiasing)
        
        # 绘制半透明圆形背景
        painter.setPen(QPen(QColor("#4a5568"), 1.5))
        if not app_state.waiting_for_wake:
            painter.setBrush(QBrush(QColor("#2e3a50")))
        elif app_state.server_connected:
            painter.setBrush(QBrush(QColor("#1e2230")))
        else:
            painter.setBrush(QBrush(QColor("#1a1c25")))
        painter.drawEllipse(15, 15, 90, 90)
        
        # 绘制麦克风图标
        self.draw_beautiful_mic(painter)
        
        # 绘制状态指示灯
        self.draw_indicator(painter)
        
        # 绘制连接状态指示器
        self.draw_connection_indicator(painter)
        
        # 绘制指令显示区域
        self.draw_command_label(painter)
    
    def draw_beautiful_mic(self, painter):
        """绘制精美的麦克风图标"""
        # 麦克风底座
        painter.setPen(QPen(QColor("#e2e8f0"), 2))
        painter.setBrush(Qt.NoBrush)
        painter.drawEllipse(40, 35, 40, 40)
        
        # 内部装饰环
        painter.setPen(QPen(QColor("#94a3b8"), 1))
        painter.drawEllipse(45, 40, 30, 30)
        
        # 中心点 - 蓝色能量核心
        if app_state.is_recording:
            # 录音时脉冲效果
            core_size = 0.5 + abs(math.sin(self.animation_counter / 2))
            core_size = max(5, min(10, core_size * 10))
            painter.setPen(Qt.NoPen)
            painter.setBrush(QBrush(QColor("#00aaff")))
            # 将浮点数转为整数
            painter.drawEllipse(int(60 - core_size/2), int(55 - core_size/2), int(core_size), int(core_size))
        else:
            painter.setPen(Qt.NoPen)
            painter.setBrush(QBrush(QColor("#0088ff")))
            painter.drawEllipse(55, 50, 10, 10)
        
        # 支撑杆
        painter.setPen(QPen(QColor("#e2e8f0"), 2))
        painter.drawLine(60, 75, 60, 85)
        painter.drawLine(55, 85, 65, 85)
        
        # 格栅线
        painter.setPen(QPen(QColor("#94a3b8"), 1))
        for i in range(0, 360, 90):
            rad = math.radians(i)
            # 计算坐标后转为整数
            x1 = int(60 + 10 * math.cos(rad))
            y1 = int(55 + 10 * math.sin(rad))
            x2 = int(60 + 25 * math.cos(rad))
            y2 = int(55 + 25 * math.sin(rad))
            painter.drawLine(x1, y1, x2, y2)
        
    def draw_indicator(self, painter):
        """绘制状态指示灯"""
        if app_state.is_recording:
            # 动态呼吸效果
            intensity = int(100 + 155 * abs(math.sin(self.animation_counter / 4)))
            color = QColor(intensity, intensity, 255)
            
            # 脉动效果 - 录音时增大指示灯
            size_mult = 1 + 0.3 * abs(math.sin(self.animation_counter / 3))
            size = 15 * size_mult
            # 将浮点数转为整数
            x = int(85 - (size - 15)/2)
            y = int(20 - (size - 15)/2)
        elif app_state.server_connected:
            color = QColor("#00cc44")  # 绿色
            size = 15
            x = 85
            y = 20
        else:
            color = QColor("#ff5555")  # 红色
            size = 15
            x = 85
            y = 20
        
        painter.setPen(QPen(QColor("#ffffff"), 1))
        painter.setBrush(QBrush(color))
        # 确保坐标和尺寸是整数
        painter.drawEllipse(x, y, int(size), int(size))
    
    def draw_connection_indicator(self, painter):
        """绘制连接状态指示器"""
        if app_state.server_connected:
            color = QColor("#44ff77")
        else:
            color = QColor("#ff5566")
        
        painter.setPen(Qt.NoPen)
        painter.setBrush(QBrush(color))
        painter.setFont(self.indicator_font)
        painter.drawText(QRect(15, 15, 20, 20), Qt.AlignCenter, "●")
    
    def draw_command_label(self, painter):
        """绘制指令显示区域"""
        if self.notification_data:
            title = self.notification_data.get("title", "")
            message = self.notification_data.get("message", "")
            # 分两行显示标题和内容
            title_text = title
            message_text = message
        else:
            title_text = ""
            message_text = ""
        
        painter.setPen(QColor("#a0d2ff"))
        painter.setFont(self.command_font)
        
        # 绘制标题（第一行）
        fm = QFontMetrics(self.command_font)
        title_width = fm.width(title_text)
        x_pos = (self.width() - title_width) / 2
        painter.drawText(QRect(5, 90, 110, 15), Qt.AlignCenter, title_text)
        
        # 绘制内容（第二行）
        message_width = fm.width(message_text)
        # 如果内容超出显示范围，启用滚动效果
        if message_width > 110:
            # 计算滚动偏移量
            scroll_offset = int((self.animation_counter % 100) / 100 * (message_width - 110))
            painter.drawText(QRect(5 - scroll_offset, 105, message_width, 15), Qt.AlignLeft, message_text)
        else:
            x_pos = (self.width() - message_width) / 2
            painter.drawText(QRect(5, 105, 110, 15), Qt.AlignCenter, message_text)
    
    def update_ui(self):
        """更新用户界面"""
        self.animation_counter = (self.animation_counter + 1) % 100
        self.update()  # 触发重绘
    
    def mousePressEvent(self, event):
        """开始拖动"""
        if event.button() == Qt.LeftButton:
            self.dragging = True
            self.drag_position = event.globalPos() - self.frameGeometry().topLeft()
            event.accept()
    
    def mouseMoveEvent(self, event):
        """处理拖动"""
        if event.buttons() == Qt.LeftButton and self.dragging:
            self.move(event.globalPos() - self.drag_position)
            event.accept()
    
    def mouseReleaseEvent(self, event):
        """停止拖动"""
        if event.button() == Qt.LeftButton:
            self.dragging = False
            event.accept()
            
    def handle_notification(self, data):
        """处理通知数据"""
        self.notification_data = data
        self.update()